<template>
    <tnxel-submit-form :model="model">
        <div class="flex-v-center" :class="{'mb-3': !model.expanded, 'mb-2': model.expanded}">
            <el-checkbox v-model="model.expanded" @change="refresh(true)">
                生成扩展实现 (Repox + Impl)
            </el-checkbox>
            <el-checkbox v-model="model.queryable" @change="refresh(true)" v-if="model.expanded">
                生成分页查询方法
            </el-checkbox>
            <el-checkbox v-model="model.extended" @change="refresh(true)" v-if="extendable">
                继承父类的Repo
            </el-checkbox>
        </div>
        <tnxel-tabs v-model="type" :items="types" v-if="model.expanded"/>
        <el-form-item label="文件" label-width="44px">{{ model[type].path }}</el-form-item>
        <tnxel-alert type="error" class="mb-0" v-if="model[type].error">{{ model[type].error }}</tnxel-alert>
        <template v-else-if="model[type].code">
            <CodePreview :code="model[type].code"/>
            <div class="flex-v-center justify-content-end mt-3">
                <tnxel-button icon="fa-solid fa-floppy-disk" @click="save">
                    保存{{ types[type] }}代码到文件
                </tnxel-button>
                <tnxel-button icon="fa-solid fa-copy" @click="copy">
                    复制{{ types[type] }}代码到剪切板
                </tnxel-button>
            </div>
        </template>
    </tnxel-submit-form>
</template>

<script>
import tnx from '@/tnx';
import ModelingApp from '@/logic/modeling/entity/ModelingApp.js';
import EntityClass from '@/logic/modeling/entity/EntityClass.js';
import PersistUtil from '@/logic/modeling/util/persist.js';
import GenerateUtil from '@/logic/modeling/util/generate.js';
import MavenProjectUtil from '@/logic/maven/util/project.js';

import CodePreview from './components/CodePreview.vue';

export default {
    components: {
        CodePreview,
    },
    props: {
        app: {
            type: ModelingApp,
            required: true,
        },
        clazz: {
            type: EntityClass,
            required: true,
        },
    },
    data() {
        return {
            mavenProject: null,
            type: 'repo',
            model: {
                expanded: true,
                queryable: true,
                extended: GenerateUtil.getDefaultExtended(this.app, this.clazz),
                repo: {
                    path: null,
                    code: null,
                    info: null,
                    error: null,
                },
                repox: {
                    path: null,
                    code: null,
                    info: null,
                    error: null,
                },
                repoImpl: {
                    path: null,
                    code: null,
                    info: null,
                    error: null,
                },
            },
        };
    },
    computed: {
        types() {
            let types = {};
            let typeItem = GenerateUtil.getEntityCodeTypeItem('repo');
            types[typeItem.name] = typeItem.caption;
            for (let subItem of typeItem.subs) {
                types[subItem.name] = subItem.caption;
            }
            return types;
        },
        extendable() {
            let superClass = this.app.findClass(this.clazz.superClassId, true, true);
            if (superClass) {
                return superClass.kind.equals(this.clazz.kind);
            }
            return false;
        },
        jdkVersion() {
            return MavenProjectUtil.getVersion(tnx.app.global.modelingProject.maven).jdk;
        },
    },
    watch: {
        type() {
            this.refresh();
        },
    },
    mounted() {
        PersistUtil.loadRelativeMavenProject(this.app.path).then(mavenProject => {
            this.mavenProject = mavenProject;
            this.refresh();
        });
    },
    methods: {
        refresh(enforced) {
            if (enforced) {
                for (let type of Object.keys(this.types)) {
                    this.model[type].code = null;
                }
            }
            this.generate(this.type);
        },
        generate(type) {
            let model = this.model[type];
            if (model) {
                if (!model.path) {
                    let root = tnx.util.file.getParentDir(this.app.path);
                    model.path = GenerateUtil.getPath(root, this.mavenProject, this.clazz, type);
                }
                if (!model.code) {
                    switch (type) {
                        case 'repo': {
                            model.code = GenerateUtil.generateRepoCode(this.app, this.clazz, {
                                expanded: this.model.expanded,
                                extended: this.model.extended,
                            });
                            break;
                        }
                        case 'repox': {
                            model.code = GenerateUtil.generateRepoxCode(this.app, this.clazz, {
                                queryable: this.model.queryable,
                                extended: this.model.extended,
                            });
                            break;
                        }
                        case 'repoImpl': {
                            model.code = GenerateUtil.generateRepoImplCode(this.app, this.clazz, {
                                jdkVersion: this.jdkVersion,
                                queryable: this.model.queryable,
                                extended: this.model.extended,
                            });
                            break;
                        }
                    }
                }
            }
            return model;
        },
        save() {
            let model = this.model[this.type];
            GenerateUtil.save(model.path, model.code, this.type);
        },
        copy() {
            GenerateUtil.copy(this.model.code);
        },
    }
}
</script>

<style lang="scss" scoped>
</style>
